Introducción general al uso de R
Clase práctica 05

Autor/a
Afiliación

Ignacio Minoli
minolicnp@gmail.com

Observatorio de Biodiversidad del Bosque Atlántico (OBBA) Instituto de Biología Subtropical (IBS) - Unidad Ejecutora del CONICET - UNaM

Fecha de publicación

21 de agosto de 2024

1 Tablas en R

Las tablas nos permiten presentar información que está comprendida en pocos datos o porque es necesario interpretar valores de resultados para estadísticos específicos. No es un recurso adecuado para grandes cantidades de datos … a menos que se quiera usarlas para filtrar, hacer subsets o interactuar con los datos.

Son muchos los paquetes disponibles para crear tablas en R. Estos paquetes fueron evolucionando desde tablas planas a un alto nivel de personalización mediante argumentos muy detallados y de múltiples opciones personalizables. Las más utilizadas al momento de este curso son:

  • library(gt)
    link-> Es una opción sencilla posible para obtener una tabla estática y básica. En pocas líneas podríamos modificar las características principales de cualquier tabla como son el título, subtítulo, columnas o filas agrupadas, cuerpo y pie de tabla. No insume el desarrollo de mucho código.
library(gt)

gt(iris[1:2,]) |>
  tab_header(
    title = md("**Ejemplo de tabla gt ('Great Tables')**"),
    subtitle = md("Son las *primeras dos* filas de df iris")
  )

Ejemplo de tabla gt (‘Great Tables’)

Son las primeras dos filas de df iris

Sepal.Length Sepal.Width Petal.Length Petal.Width Species
5.1 3.5 1.4 0.2 setosa
4.9 3.0 1.4 0.2 setosa
  • library(kableExtra) link-> Es una opción que permite hacer las clásicas tablas en LaTeX que se hacían tradicionalmente en las publicaciones, pero además permite muchas personalización de colores y como alternativa se pueden crear las tablas en HTML.
library(kableExtra)

dt <- mtcars[1:5, 1:4]
dt
                   mpg cyl disp  hp
Mazda RX4         21.0   6  160 110
Mazda RX4 Wag     21.0   6  160 110
Datsun 710        22.8   4  108  93
Hornet 4 Drive    21.4   6  258 110
Hornet Sportabout 18.7   8  360 175
# HTML table
kbl(dt, caption = "Demo Table") %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = F
    ) %>%
  add_header_above(
    c(" ", "Group 1" = 2, "Group 2[note]" = 2)) %>%
  footnote(c("table footnote"))
Demo Table
Group 1
Group 2[note]
mpg cyl disp hp
Mazda RX4 21.0 6 160 110
Mazda RX4 Wag 21.0 6 160 110
Datsun 710 22.8 4 108 93
Hornet 4 Drive 21.4 6 258 110
Hornet Sportabout 18.7 8 360 175
Note:
table footnote
  • library(DT) link-> Es una gran opción para hacer tablas interactivas, filtrados, selecciones, subsets. Es ideal para usarlas en dashboards o grandes volúmenes de datos. Incluye filtros y permite ajustar entre otras cosas su paginación en el HTML para mostrar los datos de acuerdo al tamaño visual.
library(DT)

datatable(iris)


- library(reactable)
link-> Permite un nivel de personalización alto, con posibilidad de dar formatos condicionales intracelda e incluir filtros en las propias tablas. Ejemplos

library(reactable)

reactable(iris)

1.1 Personalización y estilos

En el mundo académico (publicaciones, presentaciones a congresos) y en el desarrollo (webs, informes, dashboards, etc.) hay una tendencia recientemente nueva a personalizar y dar estilos a las tablas para facilitar la lectura e interpretación de los datos presentados.

# Librerias
library(gt)
library(gtExtras)
library(tidyverse)
library(janitor)

# Set de datos de ejemplo.
df <- read_csv(
  "https://raw.githubusercontent.com/iminoli/EcoInformatics/master/pdf/Curso.R.2024/Practicos/Table3_C.csv"
  ) %>%
  clean_names()
  
glimpse(df)
Rows: 4
Columns: 7
$ season     <chr> "Winter", "Spring", "Summer", "Autumn"
$ valor_sp_a <dbl> 1378.23, 344.23, 278.99, 437.00
$ disp_sp_a  <chr> "(244.94-3572.17)", "(1.00-834.81)", "(1.00-735.09)", "(341…
$ valor_sp_b <dbl> 976.08, 523.83, 731.54, 243.33
$ disp_sp_b  <chr> "(315.63-3369.12)", "(132.16-1347.02)", "(210.78-1853.04)",…
$ valor_sp_c <dbl> 678.06, 295.11, 1251.32, 327.42
$ disp_sp_c  <chr> "(267.13-1114.78)", "(184.57-344.52)", "(316.28-2239.17)", …
df
# A tibble: 4 × 7
  season valor_sp_a disp_sp_a        valor_sp_b disp_sp_b   valor_sp_c disp_sp_c
  <chr>       <dbl> <chr>                 <dbl> <chr>            <dbl> <chr>    
1 Winter      1378. (244.94-3572.17)       976. (315.63-33…       678. (267.13-…
2 Spring       344. (1.00-834.81)          524. (132.16-13…       295. (184.57-…
3 Summer       279. (1.00-735.09)          732. (210.78-18…      1251. (316.28-…
4 Autumn       437  (341.50-599.44)        243. (131.47-42…       327. (53.83-7…
# Ejemplo de TABLA PLANA
df %>% 
  gt()
season valor_sp_a disp_sp_a valor_sp_b disp_sp_b valor_sp_c disp_sp_c
Winter 1378.23 (244.94-3572.17) 976.08 (315.63-3369.12) 678.06 (267.13-1114.78)
Spring 344.23 (1.00-834.81) 523.83 (132.16-1347.02) 295.11 (184.57-344.52)
Summer 278.99 (1.00-735.09) 731.54 (210.78-1853.04) 1251.32 (316.28-2239.17)
Autumn 437.00 (341.50-599.44) 243.33 (131.47-423.34) 327.42 (53.83-795.8)
# Ejemplo de TABLA PERSONALIZADA
df %>%
  rename("Season" = season) %>% 
  gt() %>% 
  data_color(
    columns = valor_sp_a,
    method = "numeric",
    palette = c("#D0FAE1", "#96E0B6", "#54DE92", "#07BD59")
  ) %>%
  data_color(
    columns = valor_sp_b,
    method = "numeric",
    palette = c("#F2DCDC", "#F5B6B6", "#F28383", "#DB4444")
  ) %>%
  data_color(
    columns = valor_sp_c,
    method = "numeric",
    palette = c("#F2DCDC", "#F5B6B6", "#F28383", "#DB4444")
  ) %>%
  cols_merge(
    columns = c(valor_sp_a, disp_sp_a),
    pattern = "{1} {2}"
  ) %>%
  cols_merge(
    columns = c(valor_sp_b, disp_sp_b),
    pattern = "{1} {2}"
  ) %>%
  cols_merge(
    columns = c(valor_sp_c, disp_sp_c),
    pattern = "{1} {2}"
  ) %>%
  cols_label(
    Season = html("<strong>Season</strong>"),
    valor_sp_a = html("<strong>Group sp. A</strong>"),
    valor_sp_b = html("<strong>Group sp. B</strong>"),
    valor_sp_c = html("<strong>Group sp. C</strong>")
  ) %>% 
  tab_style(cell_text(size = pct(85)),
            locations = cells_body(columns = c(valor_sp_a, valor_sp_b, valor_sp_c))
  ) %>% 
  cols_align(
    align = "center"
    ) %>% 
  cols_align(
    align = "left",
    columns = Season
    ) %>% 
  tab_header(
    title = html("<strong>Daily distance moved (m/day) for each studied area</strong>"),
    subtitle = html("Environments: <strong><span style='color:#0F9E50;'>Continuous Forest</span></strong> and <strong><span style='color:#DB4444;'>Fragmented Forest<span></strong>")
  ) %>% 
gtsave(# Guardo la tabla como archivo
  "Table_3.png" # Doy un nombre
  )

# Exploro el archivo original a ser publicado
browseURL("Table_3.png")

1.2 Objetos - Resúmenes

El paquete gt posee una serie de paquetes que están relacionados como: gtExtras y gtsummary.

library(gtsummary)

# summarize the data with our package
peng <- palmerpenguins::penguins
peng
# A tibble: 344 × 8
   species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
   <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
 1 Adelie  Torgersen           39.1          18.7               181        3750
 2 Adelie  Torgersen           39.5          17.4               186        3800
 3 Adelie  Torgersen           40.3          18                 195        3250
 4 Adelie  Torgersen           NA            NA                  NA          NA
 5 Adelie  Torgersen           36.7          19.3               193        3450
 6 Adelie  Torgersen           39.3          20.6               190        3650
 7 Adelie  Torgersen           38.9          17.8               181        3625
 8 Adelie  Torgersen           39.2          19.6               195        4675
 9 Adelie  Torgersen           34.1          18.1               193        3475
10 Adelie  Torgersen           42            20.2               190        4250
# ℹ 334 more rows
# ℹ 2 more variables: sex <fct>, year <int>
table_penguins <-
  peng |> 
  tbl_summary(
    include = c(bill_length_mm, species),
    by = sex
    )
11 missing rows in the "sex" column have been removed.
table_penguins

Characteristic

female
N = 165

1

male
N = 168

1
bill_length_mm 42.8 (37.6, 46.2) 46.8 (41.0, 50.4)
species

    Adelie 73 (44%) 73 (43%)
    Chinstrap 34 (21%) 34 (20%)
    Gentoo 58 (35%) 61 (36%)
1

Median (Q1, Q3); n (%)

2 Formatos de tablas

Pueden ser en formato LaTeX o en HTML. Las tablas HTML son más usadas y preferidas por ser livianas, fáciles de modificar y cambiar detalles gracias a lo simple que es el HTML. Anteriormente guardamos tablas como png, de esta manera es posible guardarlas en .html.

library(DT)
library(htmlwidgets)

peng_html <- palmerpenguins::penguins
peng
# A tibble: 344 × 8
   species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
   <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
 1 Adelie  Torgersen           39.1          18.7               181        3750
 2 Adelie  Torgersen           39.5          17.4               186        3800
 3 Adelie  Torgersen           40.3          18                 195        3250
 4 Adelie  Torgersen           NA            NA                  NA          NA
 5 Adelie  Torgersen           36.7          19.3               193        3450
 6 Adelie  Torgersen           39.3          20.6               190        3650
 7 Adelie  Torgersen           38.9          17.8               181        3625
 8 Adelie  Torgersen           39.2          19.6               195        4675
 9 Adelie  Torgersen           34.1          18.1               193        3475
10 Adelie  Torgersen           42            20.2               190        4250
# ℹ 334 more rows
# ℹ 2 more variables: sex <fct>, year <int>
datatable(peng_html,
                             options = list(autoWidth = TRUE),
                             filter = list(
                               position = 'top',
                               clear = FALSE
                               )
                             )
table_peng_html <- datatable(peng_html,
                             options = list(autoWidth = TRUE),
                             filter = list(
                               position = 'top',
                               clear = FALSE
                               )
                             )

saveWidget(table_peng_html, "html_table_peng.html")
browseURL("html_table_peng.html")

2.1 Fijas

Este es un ejemplo de como guardar tablas fijas no interactivas:

library(gtsummary)

# summarize the data with our package
peng <- palmerpenguins::penguins
peng
# A tibble: 344 × 8
   species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
   <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
 1 Adelie  Torgersen           39.1          18.7               181        3750
 2 Adelie  Torgersen           39.5          17.4               186        3800
 3 Adelie  Torgersen           40.3          18                 195        3250
 4 Adelie  Torgersen           NA            NA                  NA          NA
 5 Adelie  Torgersen           36.7          19.3               193        3450
 6 Adelie  Torgersen           39.3          20.6               190        3650
 7 Adelie  Torgersen           38.9          17.8               181        3625
 8 Adelie  Torgersen           39.2          19.6               195        4675
 9 Adelie  Torgersen           34.1          18.1               193        3475
10 Adelie  Torgersen           42            20.2               190        4250
# ℹ 334 more rows
# ℹ 2 more variables: sex <fct>, year <int>
table_penguins <-
  peng |> 
  tbl_summary(
    include = c(bill_length_mm, species),
    by = sex
    )
11 missing rows in the "sex" column have been removed.
table_penguins

Characteristic

female
N = 165

1

male
N = 168

1
bill_length_mm 42.8 (37.6, 46.2) 46.8 (41.0, 50.4)
species

    Adelie 73 (44%) 73 (43%)
    Chinstrap 34 (21%) 34 (20%)
    Gentoo 58 (35%) 61 (36%)
1

Median (Q1, Q3); n (%)

# Guardo la tabla como .png
table_penguins %>%
  as_gt() %>% 
  gtsave("table_penguins.png")

2.2 Interactivas

Se pueden crear tablas interactivas de dos maneras:

  • 1) Con filtros, re ordenamientos, etc.
library(DT)

datatable(OrchardSprays,
          extensions = "Buttons",
          options = list(
            paging = TRUE,
            scrollX=TRUE,
            searching = TRUE,
            ordering = TRUE,
            dom = 'Bfrtip',
            buttons = list(
                list(extend = 'csv', filename = "subset_OrchardSprays"),
                list(extend = 'excel', filename = "subset_OrchardSprays"),
                list(extend = 'pdf', filename = "subset_OrchardSprays")
                )
            )
          )
  • 2) Editables:

    • Con posibilidad de guardado: son elaboradas con Shiny.
    • Sin posibilidad de guardado en HTML.
library(rhandsontable)

# Ejemplo de dataset
base_arboles <- data.frame(
  Especie_Arbol = c(
    "Peltophorum dubium",
    "Syagrus romanzoffiana",
    "Ficus luschnathiana",
    "Handroanthus pulcherrimus",
    "Celtis tala",
    "Ceiba chodatii"
    ),
  Fecha_Talado = c(
    "2023-11-01", "2024-05-15", "2021-03-20",
    "2022-12-25", "2022-06-10", "2023-07-22"
    ),
  Luz_Existente = factor(c(
    "Low", "Medium", "Medium",
    "Medium", "Low", "High"),
    levels = c("Low", "Medium", "High")
    ),
  Temperatur_Minima = c(18.0, 15.0, 20.0, 16.0, 16.5, 18.5),
  Max_Altura_cm = as.integer(c(100, 300, 200, 75, 60, 240)),
  Existencia_Frutos = c(FALSE, FALSE, FALSE, FALSE, TRUE, FALSE)
)

base_arboles
              Especie_Arbol Fecha_Talado Luz_Existente Temperatur_Minima
1        Peltophorum dubium   2023-11-01           Low              18.0
2     Syagrus romanzoffiana   2024-05-15        Medium              15.0
3       Ficus luschnathiana   2021-03-20        Medium              20.0
4 Handroanthus pulcherrimus   2022-12-25        Medium              16.0
5               Celtis tala   2022-06-10           Low              16.5
6            Ceiba chodatii   2023-07-22          High              18.5
  Max_Altura_cm Existencia_Frutos
1           100             FALSE
2           300             FALSE
3           200             FALSE
4            75             FALSE
5            60              TRUE
6           240             FALSE
# Tabla simple editable
rhandsontable(base_arboles) %>% 
  hot_col("Fecha_Talado",
          type = "date",
          dateFormat = "YYYY-MM-DD" # formato de fecha
          ) %>% 
  hot_table(highlightRow = TRUE, # resalta fila - columna actual
            highlightCol = TRUE) %>%
  hot_cols(fixedColumnsLeft = 1, # 1ra columna inmobilizada
           manualColumnMove = TRUE, # mover columnas
           manualColumnResize = TRUE # ajustar columnas
           )

3 Reportes o documentos en R

Los reportes en R o en cualquier otro lenguaje de programación documentando los pasos de análisis estadísticos o desarrollos, son imprescindibles y casi obligatorios en trabajos colaborativos. Al programar para hacer análisis o desarrollos es natural la necesidad que nace de explicar que hace cada linea de código, como se interpretan los resultados, que supuestos estad´siticos fueron cubiertos incialmente, etc.

Para todo esto se emplea en general un lenguaje llamado Markdown y su empleo en R se denomina R Markdown.

3.1 Rmarkdown

Markdown es un lenguaje de marcado diseñado para simplificar el proceso de dar formato a un texto mediante el uso de caracteres específicos. Originalmente, se creó con el propósito de escribir contenido destinado a la web de manera más rápida y fácil en comparación con el uso directo de HTML. Aunque su uso principal es en la creación de textos para la web, Markdown también es versátil y se puede aplicar a cualquier tipo de texto, sin importar su finalidad.

Se puede combinar texto y código a través del uso de “chunks” donde se ejecutan las lineas de comando. Ir a > File > New File > R Markdown > Ok y experimentar con el archivo.

3.2 Quarto

Quarto es una herramienta de código abierto utilizada en la programación para crear y publicar documentos dinámicos, como informes, libros, presentaciones, y sitios web. Está diseñada para trabajar con varios lenguajes de programación, incluidos R, Python, Julia y Observable JavaScript, lo que la hace muy versátil.

Quarto permite a los desarrolladores combinar código, texto y resultados en un solo documento, lo que facilita la creación de documentos reproducibles y bien documentados. Además, soporta la inclusión de visualizaciones, tablas, y otros elementos interactivos. Es particularmente popular en la comunidad de ciencia de datos y académica por su capacidad de integrar análisis de datos y narrativas en un formato cohesivo.

# Ejercicio 05.1
1- Descargar Quarto desde la web [https://quarto.org/docs/get-started/](https://quarto.org/docs/get-started/) e instalarlo.
2- Abrir un documento Quarto HTML, ir a la solapa "Source".
3- Elegir un dataset de la url  https://stat.ethz.ch/R-manual/R-devel/library/datasets/html/00Index.html.
4- Crear un chunk de código con el shortcut CTRL+ALT+i y leer el dataset elegido, crear una tabla resumen con la función gt_plt_summary() y guardar la tabla como un .png.
4- Crear con ese mismo set de datos una tabla completa en html con filtros y guardarla como html filtrable.